<?php

class AuthController extends Controller_Action
{
	public function init()
	{
		$this->_disableLayout();
		$layout = $this->_getLayout();
		$layout->setLayout('login');
		//$this->_log = Zend_Registry::get('Log');
		
	}
	
	/**
	 * Обязательно переопределять preDispatch и не вызывать родителя, 
	 * ибо это единственный контроллер, который не проверяет авторизацию.
	 * 
	 * @see Controller_Action::preDispatch()
	 */
	public function preDispatch()
	{
		
	}

	public function indexAction()
	{
		// Если мы уже залогинены и при этом все еще здесь - уходим на главную
		$user = $this->getUser();
		if ($user) {
			$this->_redirect('/');
			return;
		}
		
		// Если мы только что зашли, и у нас нет кода - просто показываем вьюшку
		$client = VkClient::getInstance();
		$this->view->authUrl = $client->getAuthUrl();
		if (!$this->_getParam('code')) {
			return;
		}
		
		try {
			$adapter = new Auth_Adapter_VkCode($this->_getParam('code'));
			$result = Auth::getInstance()->authenticate($adapter);
		} catch (VkException $e) {
			if ($e->getMessage() == 'invalid_grant: Code is invalid or expired.') {
				$this->view->errors = array("Не удалось получить токен по коду, попробуйте снова.");
				return;
			}
		}
		
		if ($result->isValid()) {
			$this->_redirect('/auth/accept');
		} else {
			$this->view->errors = $result->getMessages();
		}
	}

	/**
	 * Подтверждение авторизации
	 *
	 * @throws Exception
	 */
	public function acceptAction()
	{
		$user = $this->getUser();
		if (!$user) {
			$this->_redirect('/auth');
			return;
		}
		
		if ($user->getAccessToken()) {
			// @todo Необходимо как-то проверять - действителен ли токен, но без активных действий пользователя этого похоже сделать никак нельзя.
			$this->_redirect('/auth/get.groups');
			return;
		}
		
		// Если мы уже отослали форму с токеном - обрабатываем ее, иначе просто показываем вьюшку.
		if ($this->getRequest()->isPost()) {
			$token = $this->_getParam('token');
			preg_match('/[a-f0-9]{60,70}/', $token, $matches);
			if (! isset($matches[0])) {
				$this->view->error = "Ошибка: токен не найден в строке '{$matches[0]}'";
				return;
			}
			
			$token = $matches[0];
			
			// Сохраняем token
			$user->setAccessToken($token);
			$user->save();
			$this->_redirect('/auth/get.groups');
		}
	}
	
	/**
	 * Получает группы пользователя и убеждается, что он является администратором хотя бы одной, что необходимо для продолжения.
	 * 
	 * @return void
	 */
	public function getGroupsAction()
	{
		$user = $this->getUser();
		if (!$user) {
			$this->_redirect('/auth');
			return;
		}
		
		if (!$user->getAccessToken()) {
			$this->_redirect('/auth/accept');
			return;
		}
		
		$groups = VkApi::getInstance()->getGroups(array(
				'fields' => 'members_count,counters',
				'extended' => '1', 
				'filter' => 'admin', 
				'uid' =>  $user->getVkId()
		));
		
		if (!$groups) {
			throw new Exception("No groups found");
		}
		
		// Добавляем в базу новые группы
		foreach ($groups as $group) {
			if (!$group['is_admin']) {
				continue;
			}
			
			// Чекаем наличие группы в БД
			$select = GroupsPeer::getInstance()->select();
			$select->where('vk_id = ?', $group['gid']);
			$groupRow = GroupsPeer::getInstance()->fetchRow($select);
			
			// Создаем группу, если ее не существует.
			if (!$groupRow) {
				$groupRow = GroupsPeer::getInstance()->createRow();
	        	$groupRow->setVkId($group['gid']);
			}
			
			// Обновляем параметры группы каждый раз при заходе (кроме gid)
        	$groupRow->setName($group['name']);
       		$groupRow->setUrl("http://vk.com/" . $group['screen_name']);
        	$groupRow->setPhotoBig($group['photo_big']);
        	$groupRow->setPhotoMedium($group['photo_medium']);
	
			$smallPhoto = isset($group['photo']) ? $group['photo'] : null;
        	$groupRow->setPhotoSmall($smallPhoto);
        	$groupRow->setMembersCount($group['members_count']);
        	$groupRow->setCreatedAt(date('Y-m-d H:i:s'));
        	$groupRow->setModifiedAt(date('Y-m-d H:i:s'));
        	$groupRow->save();
			
			// Чекаем наличие привязки user2group
			$select = User2groupPeer::getInstance()->select();
			$select->where('group_id = ?', $groupRow->getId());
			$select->where('user_id = ?', $user->getId());
			$user2groupRow = User2groupPeer::getInstance()->fetchRow($select);
			
			// Если привязки нет - создаем ее
			if (!$user2groupRow) {
				$user2groupRow = User2groupPeer::getInstance()->createRow();
				$user2groupRow->setGroupId($groupRow->getId());
				$user2groupRow->setUserId($user->getId());
				$user2groupRow->save();
			}
		}
		
		$this->_redirect("/");
	}

	/**
	 * Разлогинить пользователя.
	 * 
	 * @return void
	 */
	public function logoutAction()
	{
		Auth::getInstance()->onLogout();
		$this->_redirect('/auth');
	}

	/**
	 * Очистить токен. Полезно в случае непонятных ошибок.
	 * 
	 * @return void
	 */
	public function clearTokenAction()
	{
		$user = $this->getUser();
		$user->setAccessToken(null);
		$user->save();
		
		$this->_redirect('/auth/accept');
	}
}
